﻿using System;
using System.Windows.Forms;
using Lightray.Hattrick.ChppLib;
using Lightray.Hattrick.ChppLib.EntityTypes;
using System.Collections.Generic;

namespace Lightray.Hattrick
{
    public class Controller
    {
        private static SettingsFile _settings;
        private const string STORAGE_ID = "A8F537DD-7D8D-443f-AF95-BE3946690EA0";
        private const string STORAGE_PATH = ".";
        private const string SETTING_CURRENCY = "currency";
        private const string MODEL_NAME_SENIOR = "Senior Team";
        private const string MODEL_NAME_YOUTH = "Youth Team";

        private IModel _model;
        private MainForm _view;
        private StorageHandler _storage;
        ITrickStorageEntry _newEntry, _oldEntry;
        IList<ITrickStorageEntry> _entryArchive;

        public Country PreferredCurrency
        {
            get
            {
                string countryName = _settings.Get(SETTING_CURRENCY);
                if (string.IsNullOrEmpty(countryName) || !Enum.IsDefined(typeof(Country), countryName))
                    return Country.Sweden; // default
                return (Country)Enum.Parse(typeof(Country), countryName);
            }
            set
            {
                _settings.Set(SETTING_CURRENCY, value.ToString());
            }
        }

        public string[] AvailableModels 
        {
            get
            {
                return new string[] { MODEL_NAME_SENIOR, MODEL_NAME_YOUTH };
            }
        }

        public Controller()
        {
            initStorage();
            loadData();
            loadSettings();
            startView();
        }

        public void OnViewColumnSort(string columnName)
        {
            _model.Sort(columnName);
        }

        public void StartUpdateData()
        {
            Chpp chpp = new Chpp();
            chpp.DownloadPlayersAndYouthPlayersDetails(chppDownloadFinished);
        }

        public void OnViewChangeModel(string newModel)
        {
            instanceModel(newModel);
            _view.SetModel(_model);
        }

        private void instanceModel(string model)
        {
            switch (model)
            {
                case MODEL_NAME_SENIOR:
                    _model = new SeniorTeamModel(_newEntry, _oldEntry);
                    break;

                case MODEL_NAME_YOUTH:
                    _model = new YouthTeamModel(_newEntry, _oldEntry);
                    break;

                default:
                    throw new ArgumentException("Invalid model name", "newModel");
            }
        }

        private void initStorage()
        {
            _storage = new StorageHandler(STORAGE_ID, STORAGE_PATH);
        }

        private void loadData()
        {

            try
            {
                _storage.ReadPairOfLatestEntries(out _newEntry, out _oldEntry);
                _entryArchive = _storage.ReadAllEntries();
            }
            catch (Exception)
            {
                showErrorReadingFromDisk();
            }            
        }

        private void startView()
        {

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

            _view = new MainForm(this);
            connectViewEvents();
            Application.Run(_view);
        }

        void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            // redirect UI thread exceptions back to the controller
            throw e.Exception;
        }

        private void connectViewEvents()
        {            
            _view.FormClosing += new FormClosingEventHandler(onViewEnding);
        }

        private void onViewEnding(object sender, FormClosingEventArgs e)
        {
            _settings.Sync();
        }
     
        private void loadSettings()
        {
            _settings = new SettingsFile();
        }

        private void showErrorReadingFromDisk()
        {
            MessageBox.Show("Can't access archived data on disk",
                            "Error reading from disk",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
        }

        private void chppDownloadFinished(FetchResultEventArgs e)
        {
            if (e == null)
            {
                _view.UpdateFailed();
                return;
            }

            _storage.WriteNewEntry(e);            
            loadData();
            instanceModel(_view.CurrentlyShowingModel);
            _view.SetModel(_model);
            _view.UpdateFinished();
        }               
    }
}
